package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.article.mapper.ArticleConfigMapper;
import com.heima.article.mapper.ArticleContentMapper;
import com.heima.article.mapper.ArticleMapper;
import com.heima.article.service.ArticleService;
import com.heima.file.service.impl.MinIOFileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.article.dtos.ArticleHomeDto;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.pojos.ApArticleConfig;
import com.heima.model.article.pojos.ApArticleContent;
import com.heima.model.common.constants.ArticleConstants;
import com.heima.model.common.dtos.ResponseResult;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, ApArticle> implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private ArticleContentMapper articleContentMapper;

    @Autowired
    private ArticleConfigMapper articleConfigMapper;

    @Autowired
    private MinIOFileStorageService minIOFileStorageService;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 加载首页-加载更多-加载更新 三位一体
     *
     * @param dto  type=1 认为是加载更多，type=2表示加载更新
     * @param type
     * @return
     */
    @Override
    public ResponseResult load(ArticleHomeDto dto, Short type) {
        //TODO
        List<ApArticle> apArticles = new ArrayList<>();
        apArticles = articleMapper.loadArticleList(dto, type);

        //3.返回数据
        return ResponseResult.okResult(apArticles);
    }


    /**
     * 保存三剑客
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional
    public ResponseResult save(ArticleDto dto) {
        //TODO
        ApArticle apArticle = new ApArticle();
        BeanUtils.copyProperties(dto, apArticle);

        if (dto.getId() == null) {
            //1.保存文章信息
            boolean result = this.save(apArticle);
            if (!result) {
                return ResponseResult.errorResult(501,"保存文章信息失败");
            }

            //2.保存文章配置信息
            ApArticleConfig apArticleConfig = new ApArticleConfig(apArticle.getId());
            int insert = articleConfigMapper.insert(apArticleConfig);
            if(insert<1){
                throw  new RuntimeException("保存文章配置信息失败");
            }
            //3.保存文章内容信息
            ApArticleContent apArticleContent = new ApArticleContent();
            apArticleContent.setArticleId(apArticle.getId());
            apArticleContent.setContent(dto.getContent());
            articleContentMapper.insert(apArticleContent);
        }else{
            Integer count = this.lambdaQuery().eq(ApArticle::getId, dto.getId()).count();
            if (count == 0) {
                return ResponseResult.errorResult(501, "文章未找到");
            }
            boolean b = this.updateById(apArticle);
            if(!b){
                return ResponseResult.errorResult(501, "修改文章失败");
            }
            ApArticleContent content = articleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, apArticle.getId()));
            ApArticleContent apArticleContent = new ApArticleContent();
            apArticleContent.setId(content.getId());
            apArticleContent.setContent(dto.getContent());
            articleContentMapper.updateById(apArticleContent);
        }
        //文章数据已经保存，发送消息新增或修改ES中的数据
        rabbitTemplate.convertAndSend(ArticleConstants.ARTICLE_ES_SYNC_TOPIC, ArticleConstants.ARTICLE_ES_SYNC_ROUTINGKEY, JSON.toJSONString(dto));
        getFreeMark(apArticle.getId());
        //3.返回数据,要不要返回文章id ，因为wmnews表中需要
        return ResponseResult.okResult(apArticle.getId());

    }

    /**
     * FreeMarker 生成文章详情页
     * @param articleId
     */
    public void getFreeMark(Long articleId){
        // 创建配置实例

        try {
            Configuration configuration = new Configuration(Configuration.VERSION_2_3_31);
            configuration.setDirectoryForTemplateLoading(new File("src/main/resources/templates")); // 设置模板路径
            configuration.setDefaultEncoding("UTF-8");
            // 获取模板
            Template template = configuration.getTemplate("article.ftl");
            ApArticle article = this.getById(articleId);
            Map<String, Object> dataModel = new HashMap<>();
            dataModel.put("article", article);
            // 输出 HTML 文件
            Writer out = new FileWriter(new File("D:\\file/article.html"));
            template.process(dataModel, out);
            System.out.println("HTML 页面已生成！");
            //生成文件输入流
            FileInputStream inputStream = new FileInputStream("D:\\file/article.html");
            //使用MinIo的uploadHtmlFile方法将html文件存储
            minIOFileStorageService.uploadHtmlFile("D:\\file","article.html",inputStream);

            System.out.println("HTML 页面已生成！");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }


    }

}
